package server.proxy;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
import org.jboss.netty.handler.codec.http.DefaultHttpResponse;
import org.jboss.netty.handler.codec.http.HttpHeaders;
import org.jboss.netty.handler.codec.http.HttpRequest;
import org.jboss.netty.handler.codec.http.HttpResponse;
import org.jboss.netty.handler.codec.http.HttpResponseStatus;
import org.jboss.netty.handler.codec.http.HttpVersion;

import server.proxy.db.BlackList;
import server.proxy.factory.ProxySingletoneFactory;

import files.handlers.FileHandler;


/**
 * This class checks that the HTTP request ask for authorized host
 * 
 * @author Maxim
 *
 */
public class ProxyServerBlackListHandler extends SimpleChannelUpstreamHandler {
	
	private BlackList _blackList;
	
	
	public ProxyServerBlackListHandler() throws InvalidKeyException, NoSuchAlgorithmException, IllegalBlockSizeException, NoSuchPaddingException, BadPaddingException, InvalidKeySpecException, FileNotFoundException, IOException{
		
		this._blackList = ProxySingletoneFactory.getBlackList();
	}
	
	@Override
	public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception{
		
		if(isValidHost(((HttpRequest)e.getMessage()).getHeader(HttpHeaders.Names.HOST)))
				ctx.sendUpstream(e);
		else
			e.getChannel().write(createResponse(Config.ACCSESS_DENIED_HTML_FILE_NAME));
			
	}
	

	
	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
		
		System.out.println("Unexpected exception from proxy server black list handler: " + e.getCause());
		e.getChannel().close();
	}

	/**
	 * This method checks if the request host isn't blocked by this proxy server.
	 * @param hostName
	 * @return
	 * 
	 */
	private boolean isValidHost(String hostName) {
		
		return !this._blackList.isMemmber(hostName);
	}
	
	/**
	 * This method create HTTP response packet with the given message
	 * @param message
	 * @return
	 * @throws IOException
	 * 
	 */
	@SuppressWarnings("deprecation")
	private HttpResponse createResponse(String message) throws IOException{
	 	HttpResponse tResponse = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
	 	tResponse.setHeader(HttpHeaders.Names.CONTENT_TYPE, "text/html; charset=utf-8");
     
	 	ChannelBuffer tBuf = ChannelBuffers.copiedBuffer(FileHandler.readFileAsString(message), "utf-8");
     	tResponse.setContent(tBuf);
     	tResponse.setHeader("Content-Length", String.valueOf(tBuf.readableBytes()));
     
     	return tResponse;
	}
}

